﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ComClassLibrary
{
    public class Tools
    {

        /// <summary>
        /// 获取Assembly的运行路径
        /// </summary>
        ///<returns></returns>

        public static string GetAssemblyPath()
        {
            string codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
            codeBase = codeBase.Substring(8, codeBase.Length - 8);    // 8是file:// 的长度

            string[] arrSection = codeBase.Split(new char[] { '/' });
            string folderPath = "";
            for (int i = 0; i < arrSection.Length - 1; i++){
                folderPath += arrSection[i] + "/";
            }
            return folderPath;
        }

        /// <summary>
        /// 从文件中获取图片(内存流生成)
        /// </summary>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        public static Image GetImageFromFile(string FilePath)
        {
            FileStream fs = null;
            try
            {
                if (!File.Exists(FilePath))//不是绝对路径，则尝试使用相对路径
                {
                    FilePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + FilePath.Trim('\\');
                    if (!File.Exists(FilePath))//相对路径仍不存在
                        return null;
                }
                //图片文件不能超过10M
                if (new FileInfo(FilePath).Length > 10 * 1024 * 1024)
                    return null;

                fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                byte[] FileBytes = new byte[fs.Length];
                fs.Read(FileBytes, 0, FileBytes.Length);
                fs.Close();

                MemoryStream ms = new MemoryStream(FileBytes);
                Image img = Image.FromStream(ms);

                return img;
            }
            catch
            {
                return null;
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }
        }

        public static byte[] Bitmap2Byte(Bitmap bitmap)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Jpeg);
                byte[] data = new byte[stream.Length];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(data, 0, Convert.ToInt32(stream.Length));
                return data;
            }
        }

        public static byte[] Bitmap2ByteFixSize(Bitmap bitmap,int size)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Jpeg);
                byte[] data = new byte[size];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(data, 0, Convert.ToInt32(stream.Length));
                return data;
            }
        }

        public static Bitmap Byte2Bitmap(byte[] data)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream(data))
                {
                    Bitmap bm = new Bitmap(ms);
                    ms.Flush();
                    ms.Close();
                    return bm;
                }               
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return null;
            }
            
        }

        /// <summary>
        /// Convert Byte[] to Image
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static Image Bytes2Image(byte[] buffer)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream(buffer))
                {
                    Image image = System.Drawing.Image.FromStream(ms);
                    ms.Close();
                    return image;
                }               
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        //将Byte转换为结构体类型
        public static byte[] StructToBytes(object structObj)
        {
            int size = Marshal.SizeOf(structObj);
            byte[] bytes = new byte[size];
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷到分配好的内存空间
            Marshal.StructureToPtr(structObj, structPtr, false);
            //从内存空间拷贝到byte 数组
            Marshal.Copy(structPtr, bytes, 0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            return bytes;
        }

        //将Byte转换为结构体类型
        public static T ByteToStruct<T>(byte[] bytes)where T:struct
        {
            T obj = new T();
            int size = Marshal.SizeOf(obj);
            if (size > bytes.Length)
            {
                return (default(T));
            }
            //分配结构体内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将byte数组拷贝到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构体
            object tempObj = Marshal.PtrToStructure(structPtr, obj.GetType());
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);

            return (T)tempObj;
        }

        public static string Base64String2String(string base64String)
        {
            try
            {
                byte[] c = Convert.FromBase64String(base64String);
                return System.Text.Encoding.Default.GetString(c);  
            }
            catch
            {
                return base64String;
            }
            
        }

        public static MemoryStream StreamToMemoryStream(Stream instream)
        {
            MemoryStream outstream = new MemoryStream();
            const int bufferLen = 4096;
            byte[] buffer = new byte[bufferLen];
            int count = 0;
            while ((count = instream.Read(buffer, 0, bufferLen)) > 0)
            {
                outstream.Write(buffer, 0, count);
            }
            return outstream;
        }

        public static byte[] StreamToBytes(Stream stream)
        {
            var ms = StreamToMemoryStream(stream);

            byte[] bytes = new byte[ms.Length];
            

            // 设置当前流的位置为流的开始 
            ms.Seek(0, SeekOrigin.Begin);
            ms.Read(bytes, 0, bytes.Length);
            ms.Flush(); ms.Close();
            return bytes;

        }

        /// <summary>

        /// 读文件到byte[]

        /// </summary>

        /// <param name="fileName">硬盘文件路径</param>

        /// <returns></returns>

        public static byte[] ReadFileToByte(string fileName)
        {

            FileStream pFileStream = null;
            byte[] pReadByte = new byte[0];

            try
            {
                pFileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                BinaryReader r = new BinaryReader(pFileStream);
                r.BaseStream.Seek(0, SeekOrigin.Begin);    //将文件指针设置到文件开
                pReadByte = r.ReadBytes((int)r.BaseStream.Length);
                return pReadByte;
            }
            catch
            {
                return pReadByte;
            }

            finally
            {
                if (pFileStream != null)
                    pFileStream.Close();
            }
        }

        /// <summary>
        /// 写byte[]到fileName
        /// </summary>
        /// <param name="pReadByte">byte[]</param>
        /// <param name="fileName">保存至硬盘路径</param>
        /// <returns></returns>
        public static bool WriteByteToFile(byte[] pReadByte, string fileName)
        {

            FileStream pFileStream = null;
            try
            {
                //创建目录
                string dir = Path.GetDirectoryName(fileName);
                if (!Directory.Exists(dir))
                    Directory.CreateDirectory(dir);

                pFileStream = new FileStream(fileName, FileMode.OpenOrCreate);
                pFileStream.Write(pReadByte, 0, pReadByte.Length);
            }
            catch
            {
                return false;
            }
            finally
            {
                if (pFileStream != null)
                    pFileStream.Close();
            }

            return true;
        }

        #region 获取枚举的描述
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public static String GetEnumDesc(Enum e)
        {
            FieldInfo EnumInfo = e.GetType().GetField(e.ToString());
            DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[])EnumInfo.
                GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (EnumAttributes.Length > 0)
            {
                return EnumAttributes[0].Description;
            }
            return e.ToString();
        }
        #endregion

        public static DataSet ObjectArrayToDataSet(object[] objArr)
        {
            if (objArr.Length == 0)
                return null;
            DataSet ds = CreateDataSet(objArr[0].GetType());
            ds = FillDataSet(ds, objArr);
            return ds;
        }

        public static DataSet CreateDataSet(Type t)
        {
            DataSet ds = new DataSet();
            DataTable dt = new DataTable();
            ds.Tables.Add(dt);

            PropertyInfo[] pis = t.GetProperties();
            foreach (PropertyInfo pi in pis)
            {
                DataColumn dc = new DataColumn(pi.Name, pi.PropertyType);
                dt.Columns.Add(dc);
            }
            return ds;
        }

        public static DataSet FillDataSet(DataSet ds, object[] objArr)
        {
            DataColumnCollection dcs = ds.Tables[0].Columns;
            Type t = objArr[0].GetType();
            foreach (object obj in objArr)
            {
                DataRow dr = ds.Tables[0].NewRow();
                for (int i = 0; i < dcs.Count; i++)
                {
                    dr[i] = t.InvokeMember(dcs[i].ColumnName, BindingFlags.GetProperty, null, obj, null);
                }
                ds.Tables[0].Rows.Add(dr);
            }
            return ds;
        }
    }
}
